﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UIShare;
using EFong.View.Proxy;
using DevExpress.XtraGrid.Views.Grid;
using EFong.Contract;

namespace EFong.View.FlightTicket
{
    public partial class Frm_FlightTicketDetailEdit : BasicForm
    {
        private Proxy.BaseServiceProxy _baseProxy { get { return Proxy.BaseServiceProxy.GetInstance(); } }
        private Proxy.MasterServiceProxy _masterProxy { get { return Proxy.MasterServiceProxy.GetInstance(); } }

        public Frm_FlightTicketDetailEdit()
        {
            InitializeComponent();
            //this.gv_FlightWays.OptionsView.NewItemRowPosition = NewItemRowPosition.Top;
            spe_VendorDisount.SetValue(null);
            spe_Cost.SetValue(null);
            spe_NetPrice.SetValue(null);
            spe_Intergral.SetValue(null);
            spe_Discount.SetValue(null);

            cmb_BankAccount.ReadOnly(true);
        }

        protected override void InitFields()
        {
        }

        protected override void Events()
        {
            this.spe_Cost.ValueChanged += (s, e) => { updateTotalFields(); };
            this.spe_InsuranceFee.ValueChanged += (s, e) => { updateTotalFields(); };
            this.spe_InsurancePolicePrice.ValueChanged += (s, e) => { updateTotalFields(); };
            //this.spe_Intergral.ValueChanged += (s, e) => { updateTotalFields(); };
            this.spe_NetPrice.ValueChanged += (s, e) => { updateTotalFields(); };
            this.spe_Discount.ValueChanged += (s, e) => { updateTotalFields(); };
            this.spe_Price.ValueChanged += (s, e) => { updateTotalFields(); };
            this.spe_Tax1.ValueChanged += (s, e) => { updateTotalFields(); };
            this.spe_Tax2.ValueChanged += (s, e) => { updateTotalFields(); };
            this.spe_VendorDisount.ValueChanged += (s, e) => { updateTotalFields(); };

            this.cmb_Passenger.EditValueChanged += (s, e) =>
                {
                    Passenger = this.cmb_Passenger.GetValue() as Contract.Passenger;
                };

            this.cmb_InsurancePoliceType.SelectedIndexChanged += (s, e) =>
                {
                    var ipList = _masterProxy.GetInsurancePolicyByType(this.cmb_InsurancePoliceType.GetValue() as String);
                    if (Detail != null && Detail.InsurancePolicyList != null && Detail.InsurancePolicyList.Count != 0)
                    {
                        Detail.InsurancePolicyList.ForEach(ip =>
                        {
                            if (!ipList.Any(temp => temp.Ref == ip.Ref))
                                ipList.Add(ip);
                        });
                        ipList = ipList.OrderBy(ip => ip.Ref).ToList();
                    }
                    this.cmb_InsurancePolice.Properties.BindingData<Contract.InsurancePolicy>(ipList,
                        (item) =>
                        {
                            if (Detail == null)
                                return false;
                            if (Detail.InsurancePolicyList == null)
                                return false;
                            if (Detail.InsurancePolicyList.Count == 0)
                                return false;

                            if (Detail.InsurancePolicyList.Contains(item))
                                return true;

                            return false;
                        });
                };

            this.cmb_InsurancePolice.Properties.CloseUp += (s, e) =>
                {
                    List<Contract.InsurancePolicy> checkedInsurancePolicys = this.cmb_InsurancePolice.Properties.GetCheckedItems<Contract.InsurancePolicy>();

                    decimal? basePrice = null;
                    decimal? listPrice = null;

                    foreach (var item in checkedInsurancePolicys)
                    {
                        if (basePrice == null)
                            basePrice = item.BasePrice;
                        else
                            basePrice += item.BasePrice;

                        if (listPrice == null)
                            listPrice = item.ListPrice;
                        else
                            listPrice += item.ListPrice;
                    }

                    spe_InsurancePolicePrice.SetValue(basePrice);
                    spe_InsuranceFee.SetValue(listPrice);
                };

            this.cmb_JourneyOrderType.SelectedIndexChanged += (s, e) =>
                {
                    var joList = _masterProxy.GetJourneyOrderByType(this.cmb_JourneyOrderType.GetValue() as String);
                    if (Detail != null && Detail.JourneyOrderList != null && Detail.JourneyOrderList.Count != 0)
                    {
                        Detail.JourneyOrderList.ForEach(jo =>
                        {
                            if (!joList.Any(temp => temp.Ref == jo.Ref))
                                joList.Add(jo);
                        });
                        joList = joList.OrderBy(jo => jo.Ref).ToList();
                    }
                    this.cmb_JourneyOrder.Properties.BindingData<Contract.JourneyOrder>(joList,
                        (item) =>
                        {
                            if (Detail == null)
                                return false;
                            if (Detail.JourneyOrderList == null)
                                return false;
                            if (Detail.JourneyOrderList.Count == 0)
                                return false;

                            if (Detail.JourneyOrderList.Contains(item))
                                return true;

                            return false;
                        });
                };

            this.cmb_Vendor.EditValueChanged += (s, e) =>
            {
                Contract.RVendor vendor = this.cmb_Vendor.GetValue() as Contract.RVendor;

                if (vendor != null)
                {
                    SelVend = _masterProxy.GetVendorByID(vendor.ID).ReturnValue;
                }
                else
                {
                    SelVend = null;
                }
            };

            this.cmb_PaymentType.SelectedIndexChanged += (s, e) =>
            {
                if (ViewState == ViewStates.EDIT) { return; }

                this.cmb_BankAccount.SetValue(default(Contract.BankAccount));
                this.cmb_BankAccount.ReadOnly(this.cmb_PaymentType.SelectedIndex <= 0);

                //if (this.cmb_PaymentType.SelectedIndex == 0)
                this.cmb_VendorCurrency.SetValue(_baseProxy.GetCNYCurrency().ReturnValue);
                //else
                //    this.cmb_VendorCurrency.SetValue(default(Contract.Currency));
            };
            this.cmb_BankAccount.SelectedIndexChanged += (s, e) =>
            {
                Contract.BankAccount bank = this.cmb_BankAccount.GetValue() as Contract.BankAccount;
                if (bank != null)
                {
                    this.cmb_VendorCurrency.ReadOnly(true);
                    this.cmb_VendorCurrency.SetValue(bank.Currency);
                }
                else
                {
                    this.cmb_VendorCurrency.ReadOnly(false);
                    this.cmb_VendorCurrency.SetValue(default(Contract.Currency));
                }
            };


            this.cmb_JourneyType.SelectedIndexChanged += (s, e) =>
                {
                    this.gv_FlightWays.OptionsView.NewItemRowPosition = NewItemRowPosition.None;

                    if (this.cmb_JourneyType.SelectedIndex == -1)
                    {
                        this.bds_flightWay.Clear();
                    }

                    switch (this.cmb_JourneyType.GetDisplay())
                    {
                        case "单程":
                            if (this.bds_flightWay.DataSource == null)
                                break;
                            if (this.bds_flightWay.Count == 1)
                                break;
                            else if (this.bds_flightWay.Count == 0)
                            {
                                this.bds_flightWay.Add(new Contract.FlightWay());
                            }
                            else
                            {
                                for (int i = this.bds_flightWay.Count - 1; i >= 1; i--)
                                {
                                    this.bds_flightWay.RemoveAt(i);
                                }
                            }
                            break;
                        case "双程":

                            if (this.bds_flightWay.DataSource == null)
                                break;
                            if (this.bds_flightWay.Count == 2)
                                break;
                            else if (this.bds_flightWay.Count < 2)
                            {
                                for (int i = this.bds_flightWay.Count; i < 2; i++)
                                {
                                    this.bds_flightWay.Add(new Contract.FlightWay());
                                }
                            }
                            else
                            {
                                for (int i = this.bds_flightWay.Count - 1; i >= 2; i--)
                                {
                                    this.bds_flightWay.RemoveAt(i);
                                }
                            }
                            break;
                        case "联程":
                            if (ViewState == ViewStates.ADD)
                                this.gv_FlightWays.OptionsView.NewItemRowPosition = NewItemRowPosition.Top;
                            if (this.bds_flightWay.Count <= 1)
                                break;
                            break;
                        default:
                            break;
                    }

                    updateWayListValue();
                };

            this.gv_FlightWays.CellValueChanging += (s, e) =>
                {
                    if (_updatingWayList)
                        return;

                    updateWayListValue();
                };
        }

        private bool _updatingWayList;
        private void updateWayListValue()
        {
            _updatingWayList = true;
            switch (this.cmb_JourneyType.GetDisplay())
            {
                case "单程":
                    break;
                case "双程":
                    this.gv_FlightWays.SetRowCellValue(1, colDepartLocation, ((Contract.FlightWay)this.bds_flightWay[0]).Destination);
                    this.gv_FlightWays.SetRowCellValue(1, colDestination, ((Contract.FlightWay)this.bds_flightWay[0]).DepartLocation);
                    break;
                case "联程":
                    for (int i = 1; i < this.bds_flightWay.Count; i++)
                    {
                        ((Contract.FlightWay)this.bds_flightWay[i]).DepartLocation = ((Contract.FlightWay)this.bds_flightWay[i - 1]).Destination;
                        //this.gv_FlightWays.SetRowCellValue(i, colDepartLocation, ((Contract.FlightWay)this.bds_flightWay[i - 1]).Destination);
                    }
                    break;
                default:
                    break;
            }
            _updatingWayList = false;
        }

        protected override void LoadDatas()
        {
            this.cmb_JourneyOrderType.Properties.BindingData(_masterProxy.GetJourneyOrderTypeList().ReturnValue);
            this.cmb_InsurancePoliceType.Properties.BindingData(_masterProxy.GetInsurancePolicyTypeList().ReturnValue);
            //this.cmb_InsuranceVendor.Properties.BindingData(_masterProxy.GetAllInsuranceVendor().ReturnValue);


            this.bds_Vendor.BindingData(_masterProxy.GetAllFlightVendor().ReturnValue);
            this.cmb_BankAccount.Properties.BindingData(_masterProxy.GetAllEffectivedBankAccount());
            this.cmb_VendorCurrency.Properties.BindingData(_baseProxy.GetAllCurrency().ReturnValue);
        }

        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);

            if (ViewState == ViewStates.ADD && this.cmb_JourneyType.SelectedIndex == -1)
                this.cmb_JourneyType.SelectedIndex = 0;
        }

        private void updateTotalFields()
        {
            Contract.FlightOrderDatail detail = getDetail();

            this.txt_TotalPrice.SetText(detail.AccountReceivable);
            this.txt_TotalProfit.SetText(detail.Profit);
            this.txt_TotalVendorPrice.SetText(detail.AccountPayable);
            //if (spe_Intergral.GetValue() == 0)
            spe_Intergral.SetValue(detail.CulcIntergral());
        }

        private void bar_Main_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            switch (e.Item.Name)
            {
                case "bbt_Save":
                    this.save();
                    break;
                case "bbt_Close":
                    this.Close();
                    break;
                default:
                    break;
            }
        }

        private void save()
        {
            Contract.FlightOrderDatail detail = null;

            UIOperManager.SaveData(
                () =>
                {
                    return true;
                },
                () =>
                {
                    gv_FlightWays.PostEditor();
                    detail = getDetail();
                    updateToDetail(detail);
                    return true;
                },
                string.Empty,
                () =>
                {
                    DialogResult = DialogResult.OK;
                    this.Close();
                });
        }

        #region Detail
        private Contract.FlightOrderDatail _detail;
        public Contract.FlightOrderDatail Detail
        {
            get { return _detail; }
            set
            {
                _detail = value;
                onDetailChanged();
            }
        }

        private void onDetailChanged()
        {
            if (Detail == null)
            {

            }
            else
            {
                this.bds_flightWay.BindingData(Detail.FlightWayList.FilterIsDelFlightWays());
                setJourneyType();

                if (Detail.FlightOrder.Customer != null)
                {
                    Customer = _masterProxy.GetCustomerByID(Detail.FlightOrder.Customer.ID).ReturnValue;
                }

                Passenger = Detail.Passenger;

                if (Detail.Vendor != null)
                {
                    RVendor vendor = new RVendor()
                    {
                        ID = Detail.Vendor.ID,
                        Name = Detail.Vendor.Name,
                    };
                    this.cmb_Vendor.SetValue(vendor);
                }
                SelVend = Detail.Vendor;

                this.spe_ExchangeRate.SetValue(Detail.ExchangeRate);

                this.cmb_PaymentType.SetDisplay(Detail.PaymentType);
                if (Detail.BankAccount != null)
                    this.cmb_BankAccount.SetValue(Detail.BankAccount);
                if (Detail.VendorCurrency != null)
                    this.cmb_VendorCurrency.SetValue(Detail.VendorCurrency);

                txt_TicketOrderRef.SetText(Detail.AirwaysOrderNo);
                txt_TicketNo.SetText(Detail.TicketNo);

                if (Detail.Status == "留用")
                    ckb_Keep.SetValue(true);
                else
                    ckb_Keep.SetValue(false);

                //JourneyOrder = Detail.JourneyOrder;
                if (Detail.JourneyOrderList.Count > 0)
                {
                    this.cmb_JourneyOrderType.SetValue(Detail.JourneyOrderList[0].Type);
                }

                //InsurancePolicy = Detail.InsurancePolicy;
                if (Detail.InsurancePolicyList.Count > 0)
                    this.cmb_InsurancePoliceType.SetValue(Detail.InsurancePolicyList[0].Type);

                spe_Price.SetValue(Detail.Price);
                spe_Tax1.SetValue(Detail.Tax1);
                spe_Tax2.SetValue(Detail.Tax2);
                spe_InsuranceFee.SetValue(Detail.InsuranceFee);
                ckb_InsuranceFee.SetValue(Detail.IsInsurancePolicyFree);
                spe_VendorDisount.SetValue(Detail.VendorDiscount);
                spe_Cost.SetValue(Detail.Cost);
                spe_NetPrice.SetValue(Detail.NetPrice);
                spe_Intergral.SetValue(Detail.Intergral);
                spe_Discount.SetValue(Detail.Discount);

                updateTotalFields();
            }
        }

        private void setJourneyType()
        {
            if (bds_flightWay.Count == 0)
            {
                this.cmb_JourneyType.SelectedIndex = -1;
            }
            else if (bds_flightWay.Count == 1)
            {
                this.cmb_JourneyType.SelectedIndex = 0;
            }
            else if (bds_flightWay.Count == 2 && ((Contract.FlightWay)bds_flightWay[0]).DepartLocation == ((Contract.FlightWay)bds_flightWay[1]).Destination &&
                    ((Contract.FlightWay)bds_flightWay[0]).Destination == ((Contract.FlightWay)bds_flightWay[1]).DepartLocation)
            {
                this.cmb_JourneyType.SelectedIndex = 1;
            }
            else
            {
                this.cmb_JourneyType.SelectedIndex = 2;
            }
        }

        private Contract.FlightOrderDatail getDetail()
        {
            Contract.FlightOrderDatail detail = new Contract.FlightOrderDatail();

            detail.FlightWayList = this.bds_flightWay.DataSource as List<Contract.FlightWay>;

            detail.Passenger = Passenger;

            detail.AirwaysOrderNo = txt_TicketOrderRef.GetText();
            detail.TicketNo = txt_TicketNo.GetText();

            if (this.ckb_Keep.GetValue())
                detail.Status = "留用";

            //detail.JourneyOrder = JourneyOrder;
            detail.JourneyOrderList = this.cmb_JourneyOrder.Properties.GetCheckedItems<Contract.JourneyOrder>();

            //detail.InsurancePolicy = InsurancePolicy;
            detail.InsurancePolicyList = this.cmb_InsurancePolice.Properties.GetCheckedItems<Contract.InsurancePolicy>();

            detail.Price = spe_Price.GetValue();
            detail.Tax1 = spe_Tax1.GetValue();
            detail.Tax2 = spe_Tax2.GetValue();
            detail.InsuranceFee = spe_InsuranceFee.GetValue();
            detail.IsInsurancePolicyFree = ckb_InsuranceFee.GetValue();
            detail.VendorDiscount = spe_VendorDisount.GetValue();
            detail.Cost = spe_Cost.GetValue();
            detail.NetPrice = spe_NetPrice.GetValue();
            detail.Intergral = spe_Intergral.GetValue();
            detail.Discount = spe_Discount.GetValue();

            detail.Vendor = SelVend;
            detail.ExchangeRate = this.spe_ExchangeRate.GetValue();
            detail.BankAccount = this.cmb_BankAccount.GetValue() as Contract.BankAccount;
            detail.PaymentType = this.cmb_PaymentType.GetDisplay();
            detail.VendorCurrency = this.cmb_VendorCurrency.GetValue() as Contract.Currency;

            if (Detail != null)
                detail.FlightOrder = Detail.FlightOrder;

            return detail;
        }

        private void updateToDetail(Contract.FlightOrderDatail detail)
        {
            Detail.FlightWayList = detail.FlightWayList;
            Detail.Passenger = detail.Passenger;
            Detail.AirwaysOrderNo = detail.AirwaysOrderNo;
            Detail.TicketNo = detail.TicketNo;
            Detail.Status = detail.Status;
            //Detail.JourneyOrder = detail.JourneyOrder;
            //Detail.InsurancePolicy = detail.InsurancePolicy;
            Detail.Price = detail.Price;
            Detail.Tax1 = detail.Tax1;
            Detail.Tax2 = detail.Tax2;
            Detail.InsuranceFee = detail.InsuranceFee;
            Detail.IsInsurancePolicyFree = detail.IsInsurancePolicyFree;
            Detail.VendorDiscount = detail.VendorDiscount;
            Detail.Cost = detail.Cost;
            Detail.NetPrice = detail.NetPrice;
            Detail.Intergral = detail.Intergral;
            Detail.Discount = detail.Discount;

            Detail.ExchangeRate = detail.ExchangeRate;
            Detail.Vendor = detail.Vendor;
            Detail.PaymentType = detail.PaymentType;
            Detail.BankAccount = detail.BankAccount;
            Detail.VendorCurrency = detail.VendorCurrency;

            Detail.InsurancePolicyList = detail.InsurancePolicyList;
            Detail.JourneyOrderList = detail.JourneyOrderList;
        }
        #endregion

        #region Customer
        private Contract.Customer _customer;
        public Contract.Customer Customer
        {
            get { return _customer; }
            set
            {
                _customer = value;
                onCustomerChanged();
            }
        }

        private void onCustomerChanged()
        {
            if (Customer != null)
            {
                //this.cmb_Passenger.Properties.BindingData(Customer.PassengerList);
                bds_passenger.BindingData(Customer.PassengerList.FilterUnEffecivePassenger());
            }
        }
        #endregion

        #region Passenger
        private Contract.Passenger _passenger;
        public Contract.Passenger Passenger
        {
            get { return _passenger; }
            set
            {
                _passenger = value;
                onPassengerChanged();
            }
        }

        private void onPassengerChanged()
        {
            if (Passenger == null)
            {
                ControlExtensions.ClearValue(
                    cmb_Passenger,
                    txt_Sex,
                    txt_Phone,
                    txt_IDCard);
            }
            else
            {
                this.cmb_Passenger.SetValue(Passenger);

                txt_Sex.SetText(Passenger.Sex);

                string phote = string.Empty;
                if (!string.IsNullOrEmpty(Passenger.Tel1) && !string.IsNullOrEmpty(Passenger.Tel2))
                    phote = string.Format("{0} ; {1}", Passenger.Tel1, Passenger.Tel2);
                else
                    phote = string.IsNullOrEmpty(Passenger.Tel1) ? Passenger.Tel2 : Passenger.Tel1;

                txt_Phone.SetText(phote);

                string idCard = string.Empty;
                if (!string.IsNullOrEmpty(Passenger.IDCardNr1) && !string.IsNullOrEmpty(Passenger.IDCardNr2))
                    idCard = string.Format("{0} ; {1}", Passenger.IDCardNr1, Passenger.IDCardNr2);
                else
                    idCard = string.IsNullOrEmpty(Passenger.IDCardNr1) ? Passenger.IDCardNr2 : Passenger.IDCardNr1;

                txt_IDCard.SetText(idCard);
            }
        }
        #endregion

        #region JourneyOrder
        //private Contract.JourneyOrder _journeyOrder;
        //public Contract.JourneyOrder JourneyOrder
        //{
        //    get { return _journeyOrder; }
        //    set
        //    {
        //        _journeyOrder = value;
        //        onJourneyOrderChanged();
        //    }
        //}

        //private void onJourneyOrderChanged()
        //{
        //    if (JourneyOrder == null)
        //    {
        //        ControlExtensions.ClearValue(
        //            cmb_JourneyOrderType,
        //            cmb_JourneyOrder
        //            );
        //    }
        //    else
        //    {
        //        cmb_JourneyOrderType.SetValue(JourneyOrder.Type);
        //        //cmb_JourneyOrder.SetValue(JourneyOrder);
        //    }
        //}
        #endregion

        #region InsurancePolicy
        //private Contract.InsurancePolicy _insurancePolicy;
        //public Contract.InsurancePolicy InsurancePolicy
        //{
        //    get { return _insurancePolicy; }
        //    set
        //    {
        //        _insurancePolicy = value;
        //        onInsurancePolicyChanged();
        //    }
        //}

        //private void onInsurancePolicyChanged()
        //{
        //    if (InsurancePolicy == null)
        //    {
        //        ControlExtensions.ClearValue(
        //            //cmb_InsuranceVendor,
        //            cmb_InsurancePoliceType,
        //            cmb_InsurancePolice,
        //            spe_InsurancePolicePrice,
        //            spe_InsuranceFee
        //            );
        //    }
        //    else
        //    {
        //        //if(InsurancePolicy.Vendor != null)
        //        //    cmb_InsuranceVendor.SetValue(InsurancePolicy.Vendor);
        //        cmb_InsurancePoliceType.SetValue(InsurancePolicy.Type);
        //        //cmb_InsurancePolice.SetValue(InsurancePolicy);
        //        spe_InsurancePolicePrice.SetValue(InsurancePolicy.BasePrice);
        //        spe_InsuranceFee.SetValue(InsurancePolicy.ListPrice);
        //    }
        //}
        #endregion

        #region Vendor
        public Contract.Vendor SelVend { get; set; }
        #endregion

        protected override void OnViewStateChanged()
        {
            switch (ViewState)
            {
                case ViewStates.EDIT:
                    if (!AppParameters.IsAdRole)
                    {
                        gv_FlightWays.OptionsBehavior.Editable = false;
                        spe_NetPrice.ReadOnly(true);
                        spe_Cost.ReadOnly(true);
                        spe_Discount.ReadOnly(true);
                        spe_VendorDisount.ReadOnly(true);
                        spe_InsuranceFee.ReadOnly(true);
                        ckb_InsuranceFee.ReadOnly(true);
                        spe_Tax2.ReadOnly(true);
                        spe_Tax1.ReadOnly(true);
                        spe_Price.ReadOnly(true);
                        cmb_InsurancePolice.ReadOnly(true);
                        cmb_InsurancePoliceType.ReadOnly(true);
                        cmb_Vendor.ReadOnly(true);
                        cmb_VendorCurrency.ReadOnly(true);
                        cmb_PaymentType.ReadOnly(true);
                        cmb_BankAccount.ReadOnly(true);
                        spe_ExchangeRate.ReadOnly(true);
                    }
                    break;
                default:
                    break;
            }
        }
    }
}
